#include "TIM_Config.h"

/**
    ******************************************************************************
    * @file    Timer_Config.c
    * @brief   TIM4定时器配置及中断处理模块
    * @details 功能说明：
    *          - 提供1us精度的定时计数
    *          - 支持可配置的中断频率
    *          - 维护全局毫秒计数器
    * @硬件依赖：
    *          - APB1总线时钟必须配置为72MHz
    *          - 使用TIM4定时器（基本定时器）
    ******************************************************************************
    */

/* 全局变量定义 --------------------------------------------------------------*/
volatile u16 ms_HcSR04_Count = 0;  
// 作用：累计TIM4的溢出次数（单位：毫秒）
// volatile修饰原因：
// 1. 在中断和主程序间共享
// 2. 防止编译器优化导致读取旧值
// 注意：在RTOS环境中需添加互斥保护

/**
    ******************************************************************************
    * @brief  NVIC中断控制器配置（私有函数）
    * @param  无
    * @retval 无
    * @配置说明：
    *         1. 优先级分组：Group2（2位抢占优先级，2位子优先级）
    *         2. TIM4中断配置：
    *            - 抢占优先级：2（共0-3级）
    *            - 子优先级：2
    *            - 使能中断通道
    * @硬件操作：
    *         - 修改NVIC->IP[]寄存器设置优先级
    *         - 设置NVIC->ISER[]寄存器使能中断
    ******************************************************************************
    */
static void NVIC_Config(void)
{
    /* 设置NVIC优先级分组（影响所有中断） */
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

    /* 配置TIM4中断通道 */
    NVIC_InitTypeDef NVIC_InitStructure = {
        .NVIC_IRQChannel    				= TIM4_IRQn,     // TIM4中断号
        .NVIC_IRQChannelPreemptionPriority 	= 0x02,          // 抢占优先级2
        .NVIC_IRQChannelSubPriority 		= 0x02,          // 子优先级2
        .NVIC_IRQChannelCmd 				= ENABLE         // 使能中断
    };
    NVIC_Init(&NVIC_InitStructure);
}

/**
    ******************************************************************************
    * @brief  TIM4定时器初始化
    * @param  Freq: 期望的中断频率（Hz）
    * @retval 无
    * @时钟配置：
    *         - 输入时钟：APB1 72MHz
    *         - 预分频值：71 → 计数频率=72MHz/(71+1)=1MHz（1us计数）
    * @工作模式：
    *         - 向上计数模式
    *         - 自动重装载值=(1MHz/Freq)-1
    * @示例：
    *         TIM4_Config(1000) → 1ms中断周期
    ******************************************************************************
    */
void TIM4_Config(u32 Freq)
{
    /* 使能TIM4时钟（APB1总线） */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);

    /* 复位TIM4寄存器到默认值 */
    TIM_DeInit(TIM4);

    /* 时基单元配置 */
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure = {
        .TIM_Prescaler 		= 72 - 1,              // 预分频值（72分频）
        .TIM_Period 		= (1000 / Freq) - 1,   // 自动重装载值
        .TIM_ClockDivision 	= TIM_CKD_DIV1,        // 时钟不分频
        .TIM_CounterMode 	= TIM_CounterMode_Up   // 向上计数模式
    };
    TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);

    /* 清除潜在的更新中断标志 */
    TIM_ClearFlag(TIM4, TIM_FLAG_Update);

    /* 使能更新中断 */
    TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);

    /* 配置NVIC中断控制器 */
    NVIC_Config();

    /* 启动定时器 */
    TIM_Cmd(TIM4, ENABLE);
}

/**
    ******************************************************************************
    * @brief  TIM4中断服务函数（系统自动调用）
    * @param  无
    * @retval 无
    * @执行流程：
    *         1. 检查中断源是否为更新事件
    *         2. 清除中断标志位
    *         3. 递增毫秒计数器
    * @注意事项：
    *         - 必须保持短小精悍（无阻塞操作）
    *         - 实际执行时间约1.5us@72MHz
    *         - 在RTOS中需考虑临界区保护
    ******************************************************************************
    */
void TIM4_IRQHandler(void)
{
    /* 检查中断源 */
    if (TIM_GetITStatus(TIM4, TIM_IT_Update)) {
        /* 清除中断标志（硬件写1清零） */
        TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
        
        /* 毫秒计数器递增 */
        ms_HcSR04_Count++;  // 每次中断对应1ms时间
    }
}
